<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
   
      <title>4.2. Componentes complejos</title>
      <meta name="generator" content="DocBook XSL-NS Stylesheets V1.75.2">
      <link rel="home" href="indice.html" title="Manual Usuario gvHidra">
      <link rel="up" href="ch04.html" title="Cap&iacute;tulo 4. Elementos de pantalla avanzados">
      <link rel="prev" href="ch04.html" title="Cap&iacute;tulo 4. Elementos de pantalla avanzados">
      <link rel="next" href="ch04s03.html" title="4.3. Tratamiento de ficheros">
   </head>
   <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
      <div class="navheader">
         <table width="100%" summary="Navigation header">
            <tr>
               <th colspan="3" align="center">4.2. Componentes complejos</th>
            </tr>
            <tr>
               <td width="20%" align="left"><a accesskey="p" href="ch04.html">Anterior</a>&nbsp;
               </td>
               <th width="60%" align="center">Cap&iacute;tulo 4. Elementos de pantalla avanzados</th>
               <td width="20%" align="right">&nbsp;<a accesskey="n" href="ch04s03.html">Siguiente</a></td>
            </tr>
         </table>
         <hr>
      </div>
      <div class="section" title="4.2. Componentes complejos">
         <div class="titlepage">
            <div>
               <div>
                  <h2 class="title" style="clear: both"><a name="d4e3576"></a>4.2. Componentes complejos
                  </h2>
               </div>
            </div>
         </div>
             
         
             
         <p>En este punto vamos a hablar de dos componentes que se salen de los
            b&aacute;sicos para dise&ntilde;ar una pantalla gen&eacute;rica y que nos ayudar&aacute;n a la hora de
                trabajar con grupos de datos, tanto para seleccionar como para
                agrupar.
         </p>
         
             
         <div class="section" title="4.2.1. Ventana de selecci&oacute;n">
            <div class="titlepage">
               <div>
                  <div>
                     <h3 class="title"><a name="d4e3579"></a>4.2.1. Ventana de selecci&oacute;n
                     </h3>
                  </div>
               </div>
            </div>
                  
            
                  
            <p>Las ventanas de selecci&oacute;n es una particularizaci&oacute;n de las listas,
                     siendo las siguientes caracter&iacute;sticas las que las diferencian:
            </p>
            
                  
            <div class="itemizedlist">
               <ul class="itemizedlist" type="disc">
                  <li class="listitem">
                               
                     <p>Se pueden filtrar los valores posibles mediante unas b&uacute;squedas
                                  sencillas. Lo que las hace aconsejables cuando el n&uacute;mero de
                                  elementos posibles es superior a 100 aprox.
                     </p>
                             
                  </li>
                  <li class="listitem">
                               
                     <p>Se puede visualizar m&aacute;s informaci&oacute;n complementaria que nos
                                  ayude a la selecci&oacute;n de un registro, es decir, en la ventana de
                                  selecci&oacute;n se mostrar&aacute;n tantas columnas como se necesiten para la
                                  mejor comprensi&oacute;n del registro.
                     </p>
                             
                  </li>
                  <li class="listitem">
                               
                     <p>Del registro seleccionado podemos recuperar otra informaci&oacute;n
                                  que nos interese para llev&aacute;rnosla a otros campos del panel origen.
                                  Esta informaci&oacute;n puede ser visible o no en la ventana de
                                  selecci&oacute;n.
                     </p>
                             
                  </li>
                  <li class="listitem">
                               
                     <p>Nos permite tener diferentes fuentes de datos, los datos
                                  pueden venir de un web service, de base de datos, de una
                                  clase...
                     </p>
                             
                  </li>
                  <li class="listitem">
                               
                     <p>Se puede crear una ventana de selecci&oacute;n de im&aacute;genes.</p>
                             
                  </li>
               </ul>
            </div>
            
                  
            <div class="section" title="4.2.1.1. Definici&oacute;n de la ventana">
               <div class="titlepage">
                  <div>
                     <div>
                        <h4 class="title"><a name="d4e3593"></a>4.2.1.1. Definici&oacute;n de la ventana
                        </h4>
                     </div>
                  </div>
               </div>
                       
               
                       
               <p>Para definir una ventana de selecci&oacute;n tenemos que definirla en
                          la clase manejadora. Creamos una instancia de la clase <span class="bold"><strong>gvHidraSelectionWindow()</strong></span> pas&aacute;ndole el nombre de
                          campo de la tpl, campo del que depender&aacute; la ventana de selecci&oacute;n, y
                          como segundo par&aacute;metro, un identificador (p.ej. USUARIOS) del origen
                          de los datos, opcionalmente, podemos indicar una conexi&oacute;n alternativa
                          como tercer par&aacute;metro, para ello debemos indicar pasar un DSN de
                          conexi&oacute;n. Despu&eacute;s tendremos que ir relacionando los campos del panel
                          que van a ser actualizados con el campo correspondiente de la base de
                          datos, con el m&eacute;todo <span class="bold"><strong>addMatching()</strong></span>,
                          como m&iacute;nimo habr&aacute; una relaci&oacute;n ya que de lo contrario no
                          actualizar&iacute;amos ning&uacute;n campo de la ventana or&iacute;gen. Por &uacute;ltimo a&ntilde;adimos
                          esta definici&oacute;n de la ventana al panel con <span class="bold"><strong>addSelectionWindow()</strong></span>.
               </p>
               
                       
               <div class="informalexample">
                            
                  
                            <pre class="programlisting">$usuarios = new <span class="bold"><strong>gvHidraSelectionWindow</strong></span>('filUsuario','USUARIOS');
$usuarios-&gt;<span class="bold"><strong>addMatching</strong></span>('filId','id');
$usuarios-&gt;addMatching('filUsuario','usuario');
$usuarios-&gt;addMatching('filNombre','nombre');
$this-&gt;<span class="bold"><strong>addSelectionWindow</strong></span>($usuarios);</pre>
                          </div>
               
                       
               <p>Adem&aacute;s de esta definici&oacute;n b&aacute;sica la ventana tiene dos m&eacute;todos
                          que nos permitir&aacute;n customizarla:
               </p>
               
                       
               <div class="itemizedlist">
                  <ul class="itemizedlist" type="disc">
                     <li class="listitem">
                                    
                        <p><span class="bold"><strong>setSize()</strong></span>: este m&eacute;todo
                                       permite fijar el tama&ntilde;o de la ventana emergente.
                        </p>
                        
                                    
                        <div class="informalexample">
                                         
                           
                                         <pre class="programlisting">$usuarios = new gvHidraSelectionWindow('usuario','USUARIOS');
...
$usuarios-&gt;<span class="bold"><strong>setSize</strong></span>(800,600);
...</pre>
                                       </div>
                                  
                     </li>
                     <li class="listitem">
                                    
                        <p><span class="bold"><strong>setLimit()</strong></span>: este m&eacute;todo
                                       fija el n&uacute;mero m&aacute;ximo de elementos que mostrar&aacute;. Si el resultado
                                       de la consulta excede este n&uacute;mero, mostrar&aacute; un mensaje advirtiendo
                                       al usuario de que no se mostrar&aacute;n todos los resultados
                                       obtenidos.
                        </p>
                        
                                    
                        <div class="informalexample">
                                         
                           
                                         <pre class="programlisting">$usuarios = new gvHidraSelectionWindow('usuario','USUARIOS');
...
$usuarios-&gt;<span class="bold"><strong>setLimit</strong></span>(10);
...</pre>
                                       </div>
                                  
                     </li>
                     <li class="listitem">
                                    
                        <p><span class="bold"><strong>setRowsNumber()</strong></span>: este
                                       m&eacute;todo fija el n&uacute;mero de filas que se mostrar&aacute;n por pantalla
                                       simultaneamente.
                        </p>
                        
                                    
                        <div class="informalexample">
                                         
                           
                                         <pre class="programlisting">$usuarios = new gvHidraSelectionWindow('usuario','USUARIOS');
...
$usuarios-&gt;<span class="bold"><strong>setRowsNumber</strong></span>(4);
...</pre>
                                       </div>
                                  
                     </li>
                     <li class="listitem">
                                    
                        <p><span class="bold"><strong>setTemplate()</strong></span>: nos permite
                                       dise&ntilde;ar nuestra propio contenido de la ventana de selecci&oacute;n, es
                                       decir, tendr&aacute; una tpl particular en la que podremos seleccionar el
                                       tipo de componente (CampoTexto, List, Imagen, ), el nombre de la
                                       columna, el ancho de las mismas, ...
                        </p>
                        
                                    
                        <div class="informalexample">
                                         
                           
                                         <pre class="programlisting">$usuarios = new gvHidraSelectionWindow('usuario','USUARIOS');
...
$usuarios-&gt;<span class="bold"><strong>setTemplate</strong></span>('ventanaSeleccion/incUsuarios.tpl');
...</pre>
                                       </div>
                        
                                    
                        <p>Si utilizamos este m&eacute;todo significa que tenemos una
                                       plantilla (tpl) que dar&aacute; formato a la ventana de selecci&oacute;n. En
                                       caso contrario, el framework dibuja una ventana de selecci&oacute;n
                                       sencilla, en la que su contenido no es configurable.
                        </p>
                        
                                    
                        <p>Siguiendo el caso del ejemplo, debemos tener un directorio
                                       dentro del directorio plantillas, llamado "ventanaSeleccion", y
                                       dentro tendremos las tpl que correspondan a las ventanas de
                                       selecci&oacute;n de la aplicaci&oacute;n. En esa plantilla se crear&aacute;n los campos
                                       que queremos que nos sean necesarios, tanto visibles como
                                       ocultos.
                        </p>
                        
                                    
                        <div class="informalexample">
                                         
                           
                                         <pre class="programlisting">{CWImagen nombre="fichero" rutaAbs="yes" textoAsociado="Fichero" width="40" height="50"}
{CWCampoTexto nombre="nombre" size="15" textoAsociado="Nombre"}
{CWCampoTexto nombre="descripcion" size="40" textoAsociado="Descripci&oacute;n"}
{CWCampoTexto nombre="id" oculto="true"}</pre>
                                       </div>
                                  
                     </li>
                  </ul>
               </div>
               
                       
               <p>Una vez definida la ventana s&oacute;lo nos queda introducir en la tpl
                          un componente CWBotonTooltip que haga referencia a una ventana de
                          selecci&oacute;n. Para ello se parametriza indicando el campo sobre el que
                          actua (en nuestro ejemplo usuario), el form y el panel. Aqui tenemos
                          un ejemplo:
               </p>
               
                       
               <div class="informalexample">
                            
                  
                            <pre class="programlisting">{CWCampoTexto<span class="bold"><strong> nombre="filUsuarios"</strong></span> size="8" textoAsociado="Usuario"}
<span class="bold"><strong>{CWBotonTooltip</strong></span> imagen="13" titulo="Busqueda de Usuarios" funcion="abrirVS" <span class="bold"><strong>actuaSobre="filUsuarios"</strong></span> claseManejadora="TpqmVehiculosPorUsuario"}</pre>
                          </div>
               
                       
               <div class="mediaobject"><img src="images/vSeleccion.png"></div>
               
                       
               <p>Al pulsar en el bot&oacute;n tooltip de la ventana nos aparecer&aacute; una
                          ventana emergente como la siguiente:
               </p>
               
                       
               <div class="mediaobject"><img src="images/vSeleccion2.png"></div>
                     
            </div>
            
                  
            <div class="section" title="4.2.1.2. Fuentes de datos">
               <div class="titlepage">
                  <div>
                     <div>
                        <h4 class="title"><a name="d4e3647"></a>4.2.1.2. Fuentes de datos
                        </h4>
                     </div>
                  </div>
               </div>
                       
               
                       
               <p>Las definiciones particulares a la aplicaci&oacute;n, se realizar&aacute;n, al
                          igual que en el caso de las listas, se definir&aacute;n en el arranque de la
                          aplicaci&oacute;n. Para ello debemos de a&ntilde;adir su definici&oacute;n en la clase que
                          controle el panel principal de la aplicaci&oacute;n, fichero <span class="bold"><strong>AppMainWindow.php</strong></span>. Ya que el origen de los
                          datos puede ser diferente, tenemos dos formas de indicarlo:
               </p>
               
                       
               <div class="itemizedlist">
                  <ul class="itemizedlist" type="disc">
                     <li class="listitem">
                                    
                        <p><span class="bold"><strong>setSelectionWindow_DBSource($key,
                                             $query, $fields=null)</strong></span>:
                        </p>
                        
                                    
                        <p>M&eacute;todo para introducir fuente de datos con consulta
                                       SQL.
                        </p>
                        
                                    
                        <p>El primer par&aacute;metro ser&aacute; el identificador que nos es
                                       necesario cuando definimos la ventana en la clase manejadora. El
                                       segundo par&aacute;metro es la propia consulta que nos devolver&aacute; los
                                       datos a mostrar. El tercer par&aacute;metro, opcional, nos permite a&ntilde;adir
                                       campos a los que ya aparecen en la consulta, sobre ellos tambi&eacute;n
                                       se aplicar&aacute; el filtro de b&uacute;squeda.
                        </p>
                        
                                    
                        <p>En la consulta tambi&eacute;n podemos usar subconsultas. En el caso
                                       de postgres, estas han de tener siempre alias en el from (aunque
                                       no se vaya a usar) por lo que conviene ponerlo siempre (para
                                       cualquier tipo de base de datos). Notar tambi&eacute;n que en la
                                       subconsulta s&oacute;lo pondremos alias para los campos que queramos
                                       renombrar, no afectan las may&uacute;sculas / min&uacute;sculas.
                        </p>
                        
                                    
                        <div class="informalexample">
                                         
                           
                                         <pre class="programlisting">$conf-&gt;<span class="bold"><strong>setSelectionWindow_DBSource</strong></span>('USUARIOS','select id, usuario, nombre from usuarios');</pre>
                                       </div>
                                  
                     </li>
                     <li class="listitem">
                                    
                        <p><span class="bold"><strong>setSelectionWindow_ClassSource($key,
                                             $query)</strong></span>:
                        </p>
                        
                                    
                        <p>M&eacute;todo para introducir fuente de datos con una clase. Esta
                                       clase debe implementar la interfaz <span class="bold"><strong>gvHidraSelectionWindow_Source.php</strong></span>.
                        </p>
                        
                                    
                        <div class="informalexample">
                                         
                           
                                         <pre class="programlisting">$conf-&gt;<span class="bold"><strong>setSelectionWindow_ClassSource</strong></span>('PERSONAS',"PersonasSource");</pre>
                                       </div>
                                  
                     </li>
                  </ul>
               </div>
                     
            </div>
            
                  
            <div class="section" title="4.2.1.3. B&uacute;squeda en la ventana">
               <div class="titlepage">
                  <div>
                     <div>
                        <h4 class="title"><a name="d4e3669"></a>4.2.1.3. B&uacute;squeda en la ventana
                        </h4>
                     </div>
                  </div>
               </div>
                       
               
                       
               <p>La b&uacute;squeda, por defecto, busca el texto introducido en
                          cualquiera de los campos que se visualizan, y si obtenemos los datos
                          de una consulta a bd tambi&eacute;n buscar&aacute; en el array de campos a&ntilde;adidos.
                          Podemos cambiar este comportamiento de forma similar a los filtros en
                          paneles. Veamos un ejemplo:
               </p>
               
                       
               <div class="informalexample">
                            
                  
                            <pre class="programlisting">$usuarios = new gvHidraSelectionWindow('filUsuario','USUARIOS');
$usuarios-&gt;addMatching('filId','id');
$usuarios-&gt;addMatching('filUsuario','usuario');
$usuarios-&gt;addMatching('filNombre','nombre');
$usuarios-&gt;setQueryMode(2); // valor por defecto es 1
$this-&gt;addSelectionWindow($usuarios);</pre>
                          </div>
               
                       
               <p>Por defecto, cuando el usuario introduce un texto para buscar,
                          busca por todos los campos que aparecen en la consulta concatenados y
                          separados por un espacio: concat(concat(col1,' '),col2)... De esta
                          forma el usuario puede hacer una b&uacute;squeda que coincida con el final de
                          un campo y el principio del siguiente. Es importante que para las dos
                          fuentes de datos, los par&aacute;metros del matching son los que recoger&aacute;n
                          los valores y los introducir&aacute;n en la ventana destino.
               </p>
                     
            </div>
            
                  
            <div class="section" title="4.2.1.4. Dependencia">
               <div class="titlepage">
                  <div>
                     <div>
                        <h4 class="title"><a name="d4e3675"></a>4.2.1.4. Dependencia
                        </h4>
                     </div>
                  </div>
               </div>
                       
               
                       
               <p>Al igual que en las listas, tenemos la posibilidad de crear
                          ventanas de selecci&oacute;n dependientes de otros controles, aunque, en este
                          caso, podemos definir dos tipos de dependencia (fuerte o d&eacute;bil). La
                          fuerte a&ntilde;ade a la WHERE de la consulta que se genere en la ventana una
                          clausula con el valor del campo del que depende sin tener en cuenta si
                          este tiene valor o no. La d&eacute;bil, s&oacute;lo lo hace si el campo tiene valor.
                          Para indicar la dependencia tenemos que hacer uso del m&eacute;todo
                          setDependence indicando los campos de la tpl, su correspondencia en la
                          BD y el tipo de dependencia deseado :0-&gt; fuerte(valor por defecto)
                          o 1-&gt; d&eacute;bil. En nuestro ejemplo, ser&iacute;a:
               </p>
               
                       
               <div class="informalexample">
                            
                  
                            <pre class="programlisting">$usuarios = new <span class="bold"><strong>gvHidraSelectionWindow</strong></span>('filUsuario','USUARIOS');
$usuarios-&gt;addMatching('filId','id');
$usuarios-&gt;addMatching('filUsuario','usuario');
$usuarios-&gt;addMatching('filNombre','nombre');
$usuarios-&gt;<span class="bold"><strong>setDependence</strong></span>(array('esDePersonal'),array('tper_ocupacion.esPersonal'),0);
$this-&gt;addSelectionWindow($usuarios);</pre>
                          </div>
                     
            </div>
                
         </div>
         
             
         <div class="section" title="4.2.2. Selector">
            <div class="titlepage">
               <div>
                  <div>
                     <h3 class="title"><a name="d4e3682"></a>4.2.2. Selector
                     </h3>
                  </div>
               </div>
            </div>
                  
            
                  
            <p>El selector corresponde con el plugin CWSelector, es un plugin que
                     a&uacute;n est&aacute; poco elaborado, se cre&oacute; para representar relaciones 1:N dentro
                     de un mismo panel. De todos modos, la implementaci&oacute;n es manual, es
                     decir. el programador ser&aacute; el que realice las operaciones.
            </p>
            
                  
            <p>Aqu&iacute; vemos el aspecto que nos dar&aacute; el selector en una
                     pantalla.
            </p>
            
                  
            <div class="mediaobject"><img src="images/selector.png"></div>
            
                  
            <p>Vamos a explicar como hacer uso de &eacute;l:</p>
            
                  
            <div class="itemizedlist">
               <ul class="itemizedlist" type="disc">
                  <li class="listitem">
                               
                     <p><span class="emphasis"><em>En la plantilla (tpl)</em></span>:
                     </p>
                     
                               
                     <p>El plugin CWSelector solamente aparecer&aacute; dentro de una ficha
                                  (CWFicha). CWSelector es un plugin block, dentro del cual podremos
                                  definir otros componentes, como CWCampoTexto y CWLista.
                     </p>
                     
                               
                     <div class="informalexample">
                                    
                        
                                    <pre class="programlisting">{CWSelector titulo="TituloDelGrupo" botones=$smty_botones nombre="listaBienes" editable="true" separador="."}
    {CWCampoTexto nombre="CampoTexto1" editable="false" size="6" textoAsociado="CampoTexto1"}
    {CWCampoTexto nombre="CampoTexto2" editable="false" size="6" textoAsociado="CampoTexto1"}
    {CWCampoTexto nombre="CampoTexto3" editable="false" size="6" textoAsociado="CampoTexto1"}
{/CWSelector}</pre>
                                  </div>
                     
                               
                     <p>Los valores introducidos en estos campos ser&aacute;n copiados,
                                  cuando pulsamos el bot&oacute;n <span class="inlinemediaobject"><img src="images/flechaIzq.gif"></span>, a la lista m&uacute;ltiple que tenemos en la parte
                                  izquierda, separando los valores por el caracter introducido en el
                                  par&aacute;metro <span class="emphasis"><em>separador</em></span>, en nuestro ejemplo el
                                  punto.
                     </p>
                     
                               
                     <p>Con el bot&oacute;n <span class="inlinemediaobject"><img src="images/flechaDcha.gif"></span>, copiaremos los valores que est&eacute;n
                                  seleccionados en la lista m&uacute;ltiple a los campos que hayamos definido
                                  dentro del selector.
                     </p>
                     
                               
                     <p>Finalmente, el bot&oacute;n <span class="inlinemediaobject"><img src="images/42.gif"></span> nos servir&aacute; para eliminar el registro que
                                  tengamos seleccionado en la lista m&uacute;ltiple.
                     </p>
                             
                  </li>
                  <li class="listitem">
                               
                     <p><span class="emphasis"><em>En el views</em></span>:
                     </p>
                     
                               
                     <p>En el views tenemos que indicar qu&eacute; botones del selector
                                  tendremos activos, para ello asignamos la variable smarty
                                  <span class="emphasis"><em>smty_botones</em></span>.
                     </p>
                     
                               
                     <div class="informalexample">
                                    
                        
                                    <pre class="programlisting">$botones = array('insertar','modificar','eliminar');
$s-&gt;assign("smty_botones",$botones);</pre>
                                  </div>
                             
                  </li>
                  <li class="listitem">
                               
                     <p><span class="emphasis"><em>En la clase manejadora</em></span>:
                     </p>
                     
                               
                     <p>Finalmente, &iquest;como recuperamos el contenido del Selector en la
                                  clase manejadora? Recordemos que el contenido del selector devolver&aacute;
                                  una lista, ya que podemos tener N items, pero al recibirlo en la
                                  clase manejadora, s&oacute;lo recibimos un string de elementos separados
                                  por separador. Por esta raz&oacute;n, para obtener un array podemos
                                  utilizar el siguiente c&oacute;digo:
                     </p>
                     
                               
                     <div class="informalexample">
                                    
                        
                                    <pre class="programlisting">public function postInsertar($objDatos) {

    $m_datos = $objDatos-&gt;getAllTuplas();
    foreach($m_datos as $tupla) {
       if($tupla['listaBienes']!='') {       
           echo 'El resultado es: ';
           print_r($tupla['listaBienes']);die;
       }
    ...
}</pre>
                                  </div>
                     
                               
                     <p>Si hubi&eacute;ramos introducido los siguientes valores en nuestro
                                  ejemplo:
                     </p>
                     
                               
                     <div class="mediaobject"><img src="images/ejSelector.png"></div>
                     
                               
                     <p>El resultado ser&iacute;a:</p>
                     
                               
                     <div class="informalexample">
                                    
                        
                                    <pre class="programlisting">Array
(
    [0] =&gt; 1.2.3
    [1] =&gt; 4.5.6
)</pre>
                                  </div>
                             
                  </li>
               </ul>
            </div>
                
         </div>
           
      </div>
      <div class="navfooter">
         <hr>
         <table width="100%" summary="Navigation footer">
            <tr>
               <td width="40%" align="left"><a accesskey="p" href="ch04.html">Anterior</a>&nbsp;
               </td>
               <td width="20%" align="center"><a accesskey="u" href="ch04.html">Subir</a></td>
               <td width="40%" align="right">&nbsp;<a accesskey="n" href="ch04s03.html">Siguiente</a></td>
            </tr>
            <tr>
               <td width="40%" align="left" valign="top">Cap&iacute;tulo 4. Elementos de pantalla avanzados&nbsp;</td>
               <td width="20%" align="center"><a accesskey="h" href="indice.html">Inicio</a></td>
               <td width="40%" align="right" valign="top">&nbsp;4.3. Tratamiento de ficheros</td>
            </tr>
         </table>
      </div>
   </body>
</html>